package com.fingard.dsp.bank.directbank.chinapay01;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fingard.constant.DateFormat2;
import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.directbank.chinapay01.util.DemoBase;
import com.fingard.dsp.bank.reqrespobj.statement.RefundState;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.MixFtp;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.util.FtpUtil;

/**
 * 中国银联对账单获取 支持交易：快捷支付、网关支付
 * 
 * @author Cruise
 * @date 2018年09月21日
 */
public class ChinaPay01Statement extends ChinaPay01Base implements IStatement {
	public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
		RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
		retAts.writeStart();

		String[] smsRecRespHeader = getSmsRecStatement(p_reqQrySttm, retAts);
		String smsRecTotalNum = retAts.totalNum;

		String[] gatewayRespHeader = getGatewayStatement(p_reqQrySttm, retAts);
		String gatewayTotalNum = retAts.totalNum;

		String[] PosRecRespHeader = getPosRecStatement(p_reqQrySttm, retAts);
		String PosRecTotalNum = retAts.totalNum;

		if ("-1".equals(smsRecRespHeader[0]) && "-1".equals(gatewayRespHeader[0]) && "-1".equals(PosRecRespHeader[0])) {
			retAts.writeRespCode("-1");
			retAts.writeRespInfo("快捷支付对账单获取失败原因:" + smsRecRespHeader[1] + ",网关支付对账单获取失败原因:" + gatewayRespHeader[1]+ ",POS对账单获取失败原因:" + PosRecRespHeader[1]);
		} else {
			if (retAts.getWrittenRdCount() == 0) {
				retAts.writeRespCode("0");
				retAts.writeRespInfo("本日无交易记录!");
			}
			retAts.isWritedTotalNum(String.valueOf(Integer.parseInt(smsRecTotalNum) + Integer.parseInt(gatewayTotalNum))+ Integer.parseInt(PosRecTotalNum));
		}

		retAts.writeEnd();
		return retAts;
	}

	/**
	 * 快捷支付对账单获取
	 * 
	 * @param p_reqQrySttm
	 * @param retAts
	 * @return
	 * @throws Exception
	 */
	private String[] getSmsRecStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
		String[] tmpRespHeader = new String[] { "", "" };

		String tmpRespCode = "-1";
		String tmpRespInfo = "";

		retAts.totalNum = "0";
		int totalNum = 0;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "smsRec");
			if (actItem != null) {
				Map<String, String> mapParams = new HashMap<String, String>();

				mapParams.put("version", "5.1.0");
				mapParams.put("encoding", getCharset());
				mapParams.put("signMethod", "01");
				mapParams.put("txnType", "76");
				mapParams.put("txnSubType", "01");
				mapParams.put("bizType", "000000");
				mapParams.put("accessType", "0");
				mapParams.put("merId", actItem.merchantId);
				mapParams.put("settleDate", new DateFormat2("MMdd").format(p_reqQrySttm.getBusDate()));
				mapParams.put("txnTime", Format.DateTime14Format.format(new Date()));
				mapParams.put("fileType", "00");

				Map<String, String> rspData = sendToBank(mapParams, actItem, bankFront.getUrl("qrySmsRecStatement"));

				String respCode = rspData.get("respCode");
				if ("00".equals(respCode)) {
					tmpRespCode = "0";
					
					String zipFilePath = deCodeFileContent(rspData);
					List<String> fileList = DemoBase.unzip(zipFilePath, getTempFileDirectory());
					for (String file : fileList) {
						String tmpStrRet = "";
						if (file.indexOf("ZME_") != -1) {
							continue;
						}
						if (file.indexOf("ZM_") > -1) {
							tmpStrRet = FileHelper.readFileText(file, getCharset());
						}
						WriteBankLogLn2("银联对账单响应数据:\r\n" + tmpStrRet);
						String[] totalLine = tmpStrRet.split("\r\n");
						for (String eachLine : totalLine) {
							if (eachLine.length() > 0) {
								totalNum++;
								RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();

								tmpRetDetail.askNumber = eachLine.substring(112, 145).trim();
								tmpRetDetail.amount = StringHelper.amountDivide100(
										String.valueOf(Long.parseLong(eachLine.substring(66, 78).trim())));
								tmpRetDetail.fee = StringHelper.amountDivide100(eachLine.substring(167, 179).trim());
								tmpRetDetail.busTime = p_reqQrySttm.busDate + eachLine.substring(39, 45).trim();
								tmpRetDetail.cdFlag = "22";
								tmpRetDetail.oppAct = eachLine.substring(46, 65).trim();
								tmpRetDetail.transState = TransState.Success;

								retAts.writeRetDetail(tmpRetDetail);
							}
						}
					}
				} else {
					tmpRespCode = "-1";
					tmpRespInfo = rspData.get("respMsg");
					if (tmpRespInfo.contains("无文件")) {
						tmpRespCode = "0";
					}
				}
			} else {
				tmpRespCode = "-1";
				tmpRespInfo = "未找到账号[" + p_reqQrySttm.actNum + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.totalNum = String.valueOf(totalNum);

		tmpRespHeader[0] = tmpRespCode;
		tmpRespHeader[1] = tmpRespInfo;

		return tmpRespHeader;
	}

	/**
	 * 网关支付对账单下载
	 * 
	 * @param p_reqQrySttm
	 * @param retAts
	 * @return
	 * @throws Exception
	 */
	public String[] getGatewayStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) throws Exception {
		String[] tmpRespHeader = new String[] { "", "" };

		String tmpRespCode = "";
		String tmpRespInfo = "";

		retAts.totalNum = "0";
		int totalNum = 0;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "gateway");
			if (actItem != null) {
				// FTP服务器配置信息
				String ftpHost = getBankConfig().getMapValueByKey("ftpMapping", "ftpHost");
				int ftpPort = Integer.parseInt(getBankConfig().getMapValueByKey("ftpMapping", "ftpPort"));

				// FTP登录用户信息
				String ftpUserName = getBankConfig().getMapValueByKey("ftpMapping", "ftpUserName");
				String ftpPassword = getBankConfig().getMapValueByKey("ftpMapping", "ftpPassword");

				// 对账单文件所在目录
				String ftpPath = getBankConfig().getMapValueByKey("ftpMapping", "ftpPath");

				// 本地路径
				String localPath = getBankConfig().getMapValueByKey("ftpMapping", "localPath");
				String fileName = getBankConfig().getMapValueByKey("ftpMapping", "fileName");

				// 从FTP下载对账单
				FtpUtil.downloadFtpFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, localPath, fileName);

				// 从本地文件读取对账单数据
				String filePath = localPath + File.separator + fileName;
				String ftpFileContent = FtpUtil.getTextFromFile(filePath, getCharset());

				if (ftpFileContent.equals("")) {
					tmpRespCode = "-1";
					tmpRespInfo = "读取对账单文件失败!";
				}

				// 返回对账单文件数据
				WriteBankLogStep3(ftpFileContent);

				// 解析上海银联网关对账单
				String[] totalLine = ftpFileContent.split("\r\n");
				if (totalLine.length > 1) {
					tmpRespCode = "0";

					// 总笔数 = 支付 + 退款 + 退款撤销 + 冲正
					String[] totalInfo = totalLine[0].split("\\|");
					int allNum = Integer.parseInt(totalInfo[2].trim()) + Integer.parseInt(totalInfo[5].trim())
							+ Integer.parseInt(totalInfo[7].trim()) + Integer.parseInt(totalInfo[9].trim());
					totalNum = allNum;

					// 获取对账单详细内容
					StringReader strReader = new StringReader(ftpFileContent);
					BufferedReader tmpReader = new BufferedReader(strReader);

					tmpReader.readLine();

					String line = "";
					while ((line = tmpReader.readLine()) != null) {
						String eachline = line.trim();
						if (eachline == null) {
							retAts.writeRespCode("-1");
							retAts.writeRespInfo("本日或本月无收支");
							break;
						} else {
							if (eachline.equals("")) {
								continue;
							}

							String[] values = eachline.split("\\|");
							if (values.length > 1) {
								RetAtsStatementDetail retDetail = new RetAtsStatementDetail();

								retDetail.busTime = values[0].trim();
								retDetail.busType = values[8].trim();
								retDetail.amount = values[15].trim();
								retDetail.bkSeq = values[22].trim();
								retDetail.cur = convertCurToATS(values[7].trim());
								retDetail.fee = values[14].trim();
								retDetail.refundAmt = values[13].trim();
								retDetail.transState = TransState.Success;
								retDetail.transState = TransState.Success;
								retDetail.refundState = RefundState.RefundSuccess;

								retAts.writeRetDetail(retDetail);
							} else {
								break;
							}
						}
					}
				} else {
					tmpRespCode = "-1";
					tmpRespInfo = "返回结果不符合预期!";
				}
			} else {
				tmpRespCode = "-1";
				tmpRespInfo = "未找到账号[" + p_reqQrySttm.actNum + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRespCode = "-1";
			tmpRespInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.totalNum = String.valueOf(totalNum);

		tmpRespHeader[0] = tmpRespCode;
		tmpRespHeader[1] = tmpRespInfo;

		return tmpRespHeader;
	}
	private String[] getPosRecStatement(ReqQryStatement p_reqQrySttm, RetAtsStatement retAts) {
		String[] respHeader = new String[]{"", ""};

		String tmpRespCode = "";
		String tmpRespInfo = "";

		retAts.totalNum = "0";
		int totalNum = 0;
		MixFtp mixFtp = null;
		try {
			String merchantId = p_reqQrySttm.actNum;
			ActSetItem actSetItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "pos");
			if (actSetItem != null && StringHelper.hasAnyChar(actSetItem.merchantId)) {
				merchantId = actSetItem.merchantId;
			}else{
				WriteBankLogLn2("未找到账号:[" + p_reqQrySttm.actNum + "]商户配置信息!----直接采用账号");
			}
			String downFileName1 = merchantId +"_"+ p_reqQrySttm.busDate + "_1.txt";
			String downFileName2 = merchantId +"_"+ p_reqQrySttm.busDate + "_68.txt";
			StringBuilder sbFileContent = new StringBuilder();
			String localFilePath1 = createTempFileDirectory() + File.separator + downFileName1;
			String localFilePath2 = createTempFileDirectory() + File.separator + downFileName2;
			WriteBankLogLn2("银联POS对账单保存本地路径:" + localFilePath1+"-"+downFileName2);
			String posRecRequestType = getBankConfig().getValueAsString("posRecRequestType");
			if ("ftp".equalsIgnoreCase(posRecRequestType) || "sftp".equalsIgnoreCase(posRecRequestType)) {
				FtpSet ftpSet = bankFront.getFtpSet("pos");

				WriteBankLogLn2("银联POS对账单FTP服务器地址:" + ftpSet.serverIP + ":" + ftpSet.port);
				WriteBankLogLn2("下载目录：" + ftpSet.downDir+"，下载文件名："+downFileName1);
				WriteBankLogLn2("银联POS对账单所在服务器路径:" + StringHelper.trimEnd(ftpSet.downDir, "/") + "/" + downFileName1);

				mixFtp = new MixFtp(ftpSet);
				FtpReceiver ftpReceiver = mixFtp.downloadFileFromDir(ftpSet.downDir, downFileName1, localFilePath1);
				FtpReceiver ftpReceiver2 = mixFtp.downloadFileFromDir(ftpSet.downDir, downFileName2, localFilePath2);
				if (ftpReceiver.isCompleted && ftpReceiver2.isCompleted) {
					if (sbFileContent.length() > 0) {
						sbFileContent.append("\n");
					}
					sbFileContent.append(FileHelper.readFileText(localFilePath1, "gbk"));
					sbFileContent.append(FileHelper.readFileText(localFilePath2, "gbk"));
				} else {
					tmpRespCode = "-1";
					tmpRespInfo = "银联POS对账单下载失败,原因:\r\n" + ftpReceiver.connMsg;
				}
			}else {
				String bkFolder = bankFront.getStrValueByFor("bankFolder", "pos");
				String posFile = StringHelper.trimEndFileSp(bkFolder)+File.separator+downFileName1;
				if(FileHelper.existFile(posFile)){
					if (sbFileContent.length() > 0) {
						sbFileContent.append("\n");
					}
					sbFileContent.append(FileHelper.readFileText(posFile, "UTF-8"));
				}else{
					tmpRespCode = "-1";
					tmpRespInfo = "文件"+posFile+"不存在";
				}
			}


			if (StringHelper.hasAnyChar(sbFileContent.toString())) {
				tmpRespCode = "0";

				String tmpStrRet = sbFileContent.toString();
				WriteBankLogLn2("银联POS对账单响应数据:\r\n" + tmpStrRet);

				StringReader strReader = new StringReader(tmpStrRet);
				BufferedReader tmpReader = new BufferedReader(strReader);

				boolean isContinue = false;
				while (true) {
					String eachline = tmpReader.readLine();
					if(eachline == null){
						break;
					}
					if (StringHelper.isNullOrEmpty(eachline)) {
						continue;
					}
					String[] detailNodes = eachline.split(",");
					if (merchantId.equals(detailNodes[3].trim()) && detailNodes.length==17) {
						totalNum++;
						isContinue = true;
						RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();

						if (StringHelper.hasAnyChar(detailNodes[2])) {
							tmpRetDetail.askNumber = detailNodes[9].trim();
						}
						tmpRetDetail.cdFlag = "22";
						tmpRetDetail.amount = detailNodes[6].trim();
						tmpRetDetail.fee = detailNodes[8].trim();
						tmpRetDetail.busTime = detailNodes[1]+detailNodes[2];
						tmpRetDetail.oppAct = detailNodes[3].trim();
						tmpRetDetail.transState = TransState.Success;
						retAts.writeRetDetail(tmpRetDetail);
					}
				}

				if (!isContinue) {
					tmpRespCode = "0";
					tmpRespInfo = "没有符合条件的记录!";
				}
			}

		} catch (Exception ex) {
			tmpRespCode = "-1";
			tmpRespInfo = LogHelper.getStackTrace(ex);
			WriteBankLogLn(ex);
		}finally{
			if(mixFtp!=null){
				try {
					mixFtp.disconnect();
				} catch (IOException e) {
					this.WriteBankLogLn(e);
				}
			}
		}

		retAts.totalNum = String.valueOf(totalNum);

		respHeader[0] = tmpRespCode;
		respHeader[1] = tmpRespInfo;

		return respHeader;
	}
}
